
#include "animationstackedwidget.h"
#include <QPainter>
#include <QTransform>
#include <QPropertyAnimation>
#include <QTimer>

AnimationStackedWidget::AnimationStackedWidget(QWidget *parent)
    : QStackedWidget(parent)
    , page_index_(0)
{

}

AnimationStackedWidget::~AnimationStackedWidget()
{

}

void AnimationStackedWidget::animation(int pageIndex)
{
    page_index_ = pageIndex;
    widget(page_index_)->setGeometry(frameGeometry());

    QPixmap pix(currentWidget()->size());
    currentWidget()->render(&pix);
    QPixmap pix2(widget(page_index_)->size());
    widget(page_index_)->render(&pix2);
    pix_current_.swap(pix);
    pix_next_.swap(pix2);

    QPropertyAnimation *animation = new QPropertyAnimation(this, "rotate_value");
    animation->setDuration(700);
    animation->setEasingCurve(QEasingCurve::Linear);
    animation->setStartValue(start_val_);
    animation->setEndValue(stop_val_);
    connect(animation, &QPropertyAnimation::valueChanged, this, &AnimationStackedWidget::valueChanged);
    connect(animation, &QPropertyAnimation::finished, this, &AnimationStackedWidget::finished);
    animation->start();
    QTimer::singleShot(10, [this](){
        currentWidget()->hide();
    });
}

void AnimationStackedWidget::paintEvent(QPaintEvent *event)
{
    QPainter p(this);
    p.save();
    p.setRenderHint(QPainter::SmoothPixmapTransform);
    p.setRenderHint(QPainter::Antialiasing); // 开启抗锯齿
    QTransform transform;
    transform.translate(width() / 2, height() / 2);
    if (rotate_val_ > 0 && rotate_val_ <= 90)
    {
        transform.rotate(rotate_val_, Qt::YAxis);
        p.setBrush(pix_current_);
    }
    else if (rotate_val_ > 90 && rotate_val_ < 180)
    {
        transform.rotate(rotate_val_ + 180.0, Qt::YAxis);
        p.setBrush(pix_next_);
    }
    transform.translate(-width() / 2, -height() / 2);  // 再将坐标系移回原点
    p.setTransform(transform);
    p.drawRoundedRect(QRectF(0, 0, width(), height()), 9, 9);
    p.restore();
    QStackedWidget::paintEvent(event);
}

void AnimationStackedWidget::valueChanged(const QVariant &value)
{
    // 动画开始
    update();
}

void AnimationStackedWidget::finished()
{
    // 动画结束
    setCurrentIndex(page_index_);
    QTimer::singleShot(10, [this](){
        widget(page_index_)->show();
    });
    update();
}